// 版权所有2011 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package bzip2

import (
	"bufio"
	"io"
)

// bitReader包装了一个io。读卡器，并提供从中逐位读取值的功能。它的Read*方法不会返回通常的错误
// 因为错误处理非常详细。相反，任何错误都会被保留，并且可以在事后进行检查。
type bitReader struct {
	r    io.ByteReader
	n    uint64
	bits uint
	err  error
}

// newBitReader返回从r读取的新位读取器。如果r不是
// 已经是io。ByteReader将通过bufio进行转换。读者
func newBitReader(r io.Reader) bitReader {
	byter, ok := r.(io.ByteReader)
	if !ok {
		byter = bufio.NewReader(r)
	}
	return bitReader{r: byter}
}

// ReadBits64读取给定数量的位，并在uint64的最低有效部分返回它们。如果发生错误，它返回0 
// 并且可以通过调用Err（）获得错误。
func (br *bitReader) ReadBits64(bits uint) (n uint64) {
	for bits > br.bits {
		b, err := br.r.ReadByte()
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		if err != nil {
			br.err = err
			return 0
		}
		br.n <<= 8
		br.n |= uint64(b)
		br.bits += 8
	}

	// br。n是这样的（假设br.bits=14和bits=6）：
	// Bit:111111 
	// 5432109876543210 
	// 
	// （6位，所需输出）
	// |------
	// V 
	// 0101101001110 
	// |----------
	// br。位（num有效位）
	// 
	// 下一行将所需位右移到
	// 最低有效位并屏蔽上面的任何内容。
	n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1)
	br.bits -= bits
	return
}

func (br *bitReader) ReadBits(bits uint) (n int) {
	n64 := br.ReadBits64(bits)
	return int(n64)
}

func (br *bitReader) ReadBit() bool {
	n := br.ReadBits(1)
	return n != 0
}

func (br *bitReader) Err() error {
	return br.err
}
